﻿using ScottPlot;
using ScottPlot.Plottable;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace xin2
{
    public partial class 曲线B : UserControl
    {
        #region 可自行调整修改的值
        //*S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U*//
        //默认可存放数据长度为1000000个，这个会根据当前机器内存大小适当调整，内存大的，可以大一点
        //如果内存不足以支持的话，在启动的时候会内存溢出错误，需要将它改小一点
        int maxValue = 500000;
        //线条数量，多一个就往后加一个
        double[] values1 = new double[500000];
        double[] values2 = new double[500000];
        double[] values3 = new double[500000];
        double[] values4 = new double[500000];
        //double[] values5 = new double[500000];
        //线条颜色，有几个线条，就要有几个颜色，不能多不能少，不然会报错
        List<Color> c = new List<Color>() {
                Color.Green,
                Color.Black,
                Color.Blue,
                Color.Red,
                //Color.Purple
        };
        //每一根线条的名字叫什么，和线条数量保持一致，不能多不能少，不然会报错
        List<string> labelText = new List<string> {
                "北-温度",
                "北-湿度",
                "南-温度",
                "南-湿度",
                //"数据5"
        };
        //显示出来的数据能看到多少秒的
        int showTimeData = 43200;
        #endregion
        //---------------------------------------------------------------------------------------------------------------------------------------------------------------------//

        double[] datetime;
        VLine v = new VLine();
        private Random rand = new Random();
        List<Text> texts = new List<Text>();
        List<ScatterPlot> scatters = new List<ScatterPlot>();
        List<ScatterPlot> searchScatters = new List<ScatterPlot>();
        int timer = 0;

        public 曲线B()
        {
            InitializeComponent();
        }

        private void 曲线B_Load(object sender, EventArgs e)
        {
            datetime = new double[maxValue];
            formsPlot1.Plot.XLabel("时间");
            formsPlot1.Plot.YLabel("温度");
            formsPlot1.Plot.Title("曲线");
            formsPlot1.Plot.XAxis.DateTimeFormat(true);
            InitLabel();
            DoubleBuffered = true;
            LoadData();
        }

        void LoadData()
        {

            //*S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U*//
            var scatter1 = formsPlot1.Plot.AddScatter(datetime, values1, markerSize: 0, color: c[0]);
            scatter1.Label = labelText[0];
            scatter1.IsVisible = !searchScatters.Any() || searchScatters.Any(t => t.Label == labelText[0] && t.IsVisible);
            scatters.Add(scatter1);

            var scatter2 = formsPlot1.Plot.AddScatter(datetime, values2, markerSize: 0, color: c[1]);
            scatter2.Label = labelText[1];
            scatter2.IsVisible = !searchScatters.Any() || searchScatters.Any(t => t.Label == labelText[1] && t.IsVisible);
            scatters.Add(scatter2);

            var scatter3 = formsPlot1.Plot.AddScatter(datetime, values3, markerSize: 0, color: c[2]);
            scatter3.Label = labelText[2];
            scatter3.IsVisible = !searchScatters.Any() || searchScatters.Any(t => t.Label == labelText[2] && t.IsVisible);
            scatters.Add(scatter3);

            var scatter4 = formsPlot1.Plot.AddScatter(datetime, values4, markerSize: 0, color: c[3]);
            scatter4.Label = labelText[3];
            scatter4.IsVisible = !searchScatters.Any() || searchScatters.Any(t => t.Label == labelText[3] && t.IsVisible);
            scatters.Add(scatter4);

            //var scatter5 = formsPlot1.Plot.AddScatter(datetime, values5, markerSize: 0, color: c[4]);
            //scatter5.Label = labelText[4];
            //scatter5.IsVisible = !searchScatters.Any() || searchScatters.Any(t => t.Label == labelText[4] && t.IsVisible);
            //scatters.Add(scatter5);
            //---------------------------------------------------------------------------------------------------------------------------------------------------------------------//

            formsPlot1.Plot.AxisAuto();
            formsPlot1.Refresh();
        }
        /// <summary>
        /// 启动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            if (!timer1.Enabled)
                timer1.Enabled = true;
            searchScatters.Clear();
            button1.Enabled = false;
            button3.Enabled = true;
        }
        /// <summary>
        /// 暂停，不会影响数据产生
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            button1.Enabled = true;
            button3.Enabled = false;
        }
        /// <summary>
        /// 刷新按钮，查找数据，不会影响数据产生
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            DateTime startDate = dateTimePicker1.Value;
            DateTime endDate = dateTimePicker2.Value;

            // 将DateTime转换为OADate，OADate是Excel使用的日期序列，这样可以直接使用在Plottable中
            double startOADate = startDate.ToOADate();
            double endOADate = endDate.ToOADate();

            // 获取在指定时间段内的数据
            var dateTimeSegment = datetime.Where(date => date >= startOADate && date <= endOADate).ToArray();
            label8.Text = "平均值：";
            if (dateTimeSegment.Any())
            {
                searchScatters.Clear();

                formsPlot1.Plot.SetAxisLimitsX(dateTimeSegment.First(), dateTimeSegment.Last());
                formsPlot1.Refresh();

                //*S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U*//
                // 用新的部分数据绘图
                var value1Segment = values1.Skip(datetime.TakeWhile(date => date < startOADate).Count()).Take(dateTimeSegment.Length).ToArray();
                var value2Segment = values2.Skip(datetime.TakeWhile(date => date < startOADate).Count()).Take(dateTimeSegment.Length).ToArray();
                var value3Segment = values3.Skip(datetime.TakeWhile(date => date < startOADate).Count()).Take(dateTimeSegment.Length).ToArray();
                var value4Segment = values4.Skip(datetime.TakeWhile(date => date < startOADate).Count()).Take(dateTimeSegment.Length).ToArray();
                //var value5Segment = values5.Skip(datetime.TakeWhile(date => date < startOADate).Count()).Take(dateTimeSegment.Length).ToArray();

                label8.Text = $"平均值：北-温度:{Math.Round(value1Segment.Average(), 2)}, 北-湿度:{Math.Round(value2Segment.Average(), 2)}, 南-温度:{Math.Round(value3Segment.Average(), 2)}, 南-湿度:{Math.Round(value4Segment.Average(), 2)}";
                //---------------------------------------------------------------------------------------------------------------------------------------------------------------------//

            }
            button1.Enabled = true;
            button3.Enabled = false;
        }
        /// <summary>
        /// 计时器，一秒执行一次，产生数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <exception cref="OverflowException"></exception>
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (timer >= datetime.Length)
                throw new OverflowException("数据超长，无法再添加数据");

            datetime[timer] = DateTime.Now.ToOADate();

            //*S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U*//
            //values1[timer] = double.Parse(数据显示器1.Text);
            //values2[timer] = rand.NextDouble() * 20 + 10;
            //values1[timer] = double.Parse(Form1.数据显示器11Str.Text);
            values1[timer] = double.Parse(Form1.数据显示器19Str.Text);
            values2[timer] = double.Parse(Form1.数据显示器18Str.Text);
            values3[timer] = double.Parse(Form1.数据显示器17Str.Text);
            values4[timer] = double.Parse(Form1.数据显示器16Str.Text);
            //values5[timer] = rand.NextDouble() * 20 + 10;
            //---------------------------------------------------------------------------------------------------------------------------------------------------------------------//

            if (!searchScatters.Any() && button3.Enabled)
            {
                if (timer > showTimeData)
                {
                    formsPlot1.Plot.SetAxisLimitsX(DateTime.FromOADate(datetime[timer]).AddSeconds(-showTimeData).ToOADate(), datetime[timer]);
                }
                else
                {
                    formsPlot1.Plot.AxisAuto();
                }
                scatters.ForEach(t =>
                {
                    t.MaxRenderIndex = timer;
                });
                formsPlot1.Refresh();
            }
            timer += 1;
        }

        void InitLabel()
        {
            groupBox1.Controls.Clear();
            int labelWidth = 70; // Label的宽度
            int labelHeight = 20; // Label的高度
            int distanceBetweenLabels = 20; // Label之间的距离

            for (int i = 0; i < labelText.Count; i++)
            {
                Label label1 = new Label
                {
                    Size = new Size(labelWidth, labelHeight),
                    Width = 200,
                    Text = $"——     {labelText[i]}",
                    ForeColor = c[i]
                }; // 创建Label

                // 计算Label的位置
                int row = i - 1 / 2;
                int column = i - 1 % 2;

                int x = column;
                int y = row * (labelHeight + distanceBetweenLabels);

                label1.Location = new Point(x, y);
                label1.Click += Label1_Click;
                groupBox1.Controls.Add(label1);
            }
        }
        private void Label1_Click(object sender, EventArgs e)
        {
            var lbl = (Label)sender;
            if (lbl.Text.Contains("——"))
            {
                lbl.Text = lbl.Text.Replace("——", "    ");
                searchScatters.Where(t => lbl.Text.Contains(t.Label)).ToList().ForEach(t => t.IsVisible = false);
                scatters.Where(t => lbl.Text.Contains(t.Label)).ToList().ForEach(t => t.IsVisible = false);
            }
            else
            {
                lbl.Text = lbl.Text.Replace("    ", "——");
                searchScatters.Where(t => lbl.Text.Contains(t.Label)).ToList().ForEach(t => t.IsVisible = true);
                scatters.Where(t => lbl.Text.Contains(t.Label)).ToList().ForEach(t => t.IsVisible = true);
            }
            formsPlot1.Render();
        }
        /// <summary>
        /// 清空
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;

            for (int i = 0; i <= timer; i++)
            {
                //*S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U*//
                datetime[i] = 0;
                values1[i] = 0;
                values2[i] = 0;
                values3[i] = 0;
                values4[i] = 0;
                //values5[i] = 0;
                //---------------------------------------------------------------------------------------------------------------------------------------------------------------------//

            }
            InitLabel();
            scatters.ForEach(t =>
            {
                t.IsVisible = true;
                t.MaxRenderIndex = timer;
            });
            timer = 0;
            timer1.Enabled = true;
        }
        private void formsPlot1_MouseMove(object sender, MouseEventArgs e)
        {
            // 在添加新的文本之前，首先移除所有旧的文本
            foreach (var text in texts)
            {
                formsPlot1.Plot.Remove(text);
            }
            texts.Clear();
            var tem = datetime.Where(t => t > 0);
            if (!tem.Any() || !scatters.Any())
                return;
            double mouseX = formsPlot1.Plot.GetCoordinateX(e.X);
            double mouseY = formsPlot1.Plot.GetCoordinateY(e.Y);
            formsPlot1.Plot.Remove(v);
            v = formsPlot1.Plot.AddVerticalLine(mouseX, color: Color.Red);
            double closestX = tem.OrderBy(val => Math.Abs(val - mouseX)).First();

            int index = tem.ToList().IndexOf(closestX);

            //*S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U**S*H*U*J*U*//
            double closest数据1 = values1[index];
            if (scatters.Any() && scatters.Any(t => t.Label == labelText[0] && t.IsVisible))
            {
                var text1 = formsPlot1.Plot.AddText($"{labelText[0]}: {closest数据1:n2}", closestX, closest数据1, color: Color.Fuchsia);
                texts.Add(text1);
            }
            double closest数据2 = values2[index];
            if (scatters.Any() && scatters.Any(t => t.Label == labelText[1] && t.IsVisible))
            {
                var text2 = formsPlot1.Plot.AddText($"{labelText[1]}: {closest数据2:n2}", closestX, closest数据2, color: Color.Fuchsia);
                texts.Add(text2);
            }
            double closest数据3 = values3[index];
            if (scatters.Any() && scatters.Any(t => t.Label == labelText[2] && t.IsVisible))
            {
                var text3 = formsPlot1.Plot.AddText($"{labelText[2]}: {closest数据3:n2}", closestX, closest数据3, color: Color.Fuchsia);
                texts.Add(text3);
            }
            double closest数据4 = values4[index];
            if (scatters.Any() && scatters.Any(t => t.Label == labelText[3] && t.IsVisible))
            {
                var text4 = formsPlot1.Plot.AddText($"{labelText[3]}: {closest数据4:n2}", closestX, closest数据4, color: Color.Fuchsia);
                texts.Add(text4);
            }
            //double closest数据5 = values5[index];
            //if (scatters.Any() && scatters.Any(t => t.Label == labelText[4] && t.IsVisible))
            //{
            //    var text5 = formsPlot1.Plot.AddText($"{labelText[4]}: {closest数据5:n2}", closestX, closest数据5, color: Color.Fuchsia);
            //    texts.Add(text5);
            //}
            //---------------------------------------------------------------------------------------------------------------------------------------------------------------------//

            formsPlot1.Plot.Remove(v);
            v = formsPlot1.Plot.AddVerticalLine(mouseX, color: Color.Red);
            if (timer < showTimeData)
                formsPlot1.Plot.AxisAuto();
            formsPlot1.Refresh();
        }

        private void formsPlot1_Load(object sender, EventArgs e)
        {

        }
    }
}
